package org.demo.treeeditor;

import java.awt.event.KeyEvent;

import org.boxlayout.gui.BoxLayoutEngine;
import org.boxlayout.gui.KeyCustomable;
import org.boxlayout.gui.VisualElement;
import org.demo.treeeditor.mode.BaseMode;
import org.demo.treeeditor.mode.EditMode;
import org.demo.treeeditor.mode.Modeable;

public class StateMachine {
	
	public enum StateEnum {base,move,edit,write,select}

	NodePointer currentNodePointer;
	Node bufferedNode;
	Node rootNode;

	

	BoxLayoutEngine ble;
	KeyboardManager km;
	TextPrompt tp;
	StateEnum state = StateEnum.base;
	
	
	
	Modeable baseMode;
	Modeable editMode;
	 
	Modeable currentMode;
	private HelpDisplayer helpDisplay;
	
	public StateMachine() {	
		baseMode = new BaseMode(this);
		editMode = new EditMode(this);
	}
	
	public void setRootNode(Node aNode){
		//rootVisualElement.getChilds().clear();
		ble.getRootElement().add(aNode.getVisual());
		rootNode = aNode;
		rootNode.setRoot(true);
	}

	public Node getRootNode() {
		return rootNode;
	}

	
	public BoxLayoutEngine getBoxLayoutEngine() {
		return ble;
	}

	/*public void setBoxLayoutEngine(BoxLayoutEngine ble) {
		this.ble = ble;
	}*/
	
	void handleEvent(KeyEvent e){
		if(state==StateEnum.base){
			baseMode.handleEvent(e);
		}else if(state==StateEnum.edit){
			editMode.handleEvent(e);
		}
		
	}
	
	public StateMachine setState(StateEnum state){
		this.state = state;
		return this;
	}
	
	void baseMode() {
		if(state==StateEnum.edit){
			tp.hide();
			km.setEditMode(false);
		}
		currentNodePointer.setNode(currentNodePointer.getNode());
		currentMode = baseMode;
		changeMode(currentMode);
		state=StateEnum.base;
		
		//km.clearActions();
		/*
		km.setAction("E",movePrevious);
		km.setAction("D",moveNext);
		km.setAction("F",moveToChilds);
		km.setAction("S",moveToParent);
		
		km.setAction("U",movePrevious);
		km.setAction("J",moveNext);
		km.setAction("H",moveToChilds);
		km.setAction("K",moveToParent);
		
		km.setAction("A",appendChild);
		km.setAction(32,goToEditMode);
		km.setAction(0,debug);
		*/
	}
	
	void changeMode(Modeable mode){
		this.helpDisplay.show(mode.getKeyAssignment());
	}
	
	void editMode(){
		System.out.println("EditMode");
		state=StateEnum.edit;
		//km.clearActions();
		//km.setEditMode(true);
		tp.editElement(currentNodePointer.getNode().getNameContainerVisualElement());
		//km.setAction(32,goToMoveMode);
		//km.setAction(0,debug);
	}
	

	public VisualElement getVisual(){
		return currentNodePointer.getVisual();
	}
	
	public void reSetCurrentNode() {
		currentNodePointer.setNode(currentNodePointer.getNode());
	}

	
	public StateMachine setCurrentNode(Node node) {
		currentNodePointer.setNode(node);
		ble.getCamera().moveOver(node.getNameContainerVisualElement());
		return this;
	}
	
	public Node getCurrentNode() {
		return currentNodePointer.getNode();
	}

	public StateMachine setBoxLayoutEngine(BoxLayoutEngine ble) {
		this.ble = ble;
		currentNodePointer = new NodePointer(ble);		
		//currentNodePointer.getVisual().setText("pointer");
		return this;
	}

	public void setKeyboardManager(KeyboardManager km) {
		this.km = km;
	}

	public void init() {
		ble.setOnKey(new KeyCustomable() {

			public void onKeyPressed(KeyEvent e) {
				handleEvent(e);
			}

			
			public void onKeyReleased(KeyEvent e) {
				System.out.println("onKeyReleased:" + e.getKeyCode()+" "+e.getKeyText(e.getKeyCode())+" "+e.getKeyChar());
			}
			
			public void onKeyTyped(KeyEvent e) {
				//System.out.println("onkeyTyped:" + e.getKeyCode()+" "+e.getKeyText(e.getKeyCode())+" "+e.getKeyChar());
			}

		});

		
		baseMode();
	}
	
	public void setTextPrompt(TextPrompt tp){
		this.tp=tp;
	}

	public TextPrompt getTextPrompt() {
		return tp;
	}
	
	public Node getBufferedNode() {
		return bufferedNode;
	}

	public void setBufferedNode(Node bufferedNode) {
		this.bufferedNode = bufferedNode;
	}

	public void setHelpDisplayer(HelpDisplayer hd) {
		this.helpDisplay = hd;
		
	}
	
}
